package com.xjc.infra.encrypt;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.X509Certificate;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import sun.misc.BASE64Decoder;

import com.xjc.infra.exception.IFSException;
import com.xjc.infra.util.SystemGlobals;

/**
 * 签名验签工具类
 * @author liangcz
 * @Date 2017年12月1日 下午7:43:04
 * @version 1.0
 */
@Service
public class SignUtil {
	@Autowired
	KeyFactory keyFactory;
	/**
	 * 用私钥签名
	 * @author liangcz
	 * @date   2017年12月1日 下午7:49:15
	 * @return String
	 */
	public String signMsgPriKey(String msg, PrivateKey priKey) {
		try {
			Signature signature = Signature.getInstance("SHA1withRSA");
			signature.initSign(priKey);
			signature.update(msg.getBytes(SystemGlobals.getProperty("sys.encoding","UTF-8")));
			byte[] signData = signature.sign();
			String signCode = Base64.encodeBase64String(signData);
			return signCode;
		} catch(IFSException e) {
			throw e;
		}catch (NoSuchAlgorithmException e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.95", "签名失败：找不到RSA算法的密钥生成器！");
		} catch (InvalidKeyException e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.96", "签名失败：私钥无效");
		} catch (SignatureException e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.97", "签名失败：signature执行签名失败");
		} catch (UnsupportedEncodingException e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.98", "签名失败：signature执行签名失败");
		}catch (Exception e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.99", "用私钥签名失败");
		}
	}
	/**
	 * 用私钥签名(默认签名)
	 * @author liangcz
	 * @date   2017年12月1日 下午7:54:21
	 * @return String
	 */
	public String signMsgPriKey(String msg) {
		try {
			String sign64Data = signMsgPriKey(msg,keyFactory.getPrivateKey());
			return sign64Data;
		} catch(IFSException e) {
			throw e;
		}catch (Exception e) {
			throw new IFSException(e, "SignUtil.signMsgPriKey.99", "用私钥签名失败");
		}
	}
	/**
	 * 验签
	 * @author liangcz
	 * @date   2017年12月1日 下午7:56:34
	 * @return boolean
	 */
	public boolean veriSign(String signCode, String msg,X509Certificate pubKey) {
		try {
			Signature signature = Signature.getInstance("SHA1withRSA");
			signature.initVerify(pubKey);
			signature.update(msg.getBytes(SystemGlobals.getProperty("sys.encoding","UTF-8")));
			BASE64Decoder base64Decode = new BASE64Decoder();
			byte[] signed = base64Decode.decodeBuffer(signCode);
			boolean result = signature.verify(signed);
			return result;
		} catch(IFSException e) {
			throw e;
		} catch (NoSuchAlgorithmException e) {
			throw new IFSException(e,"SignUtil.veriSign.95","验签失败：找不到RSA算法的密钥生成器");
		} catch (InvalidKeyException e) {
			throw new IFSException(e,"SignUtil.veriSign.96","验签失败：公钥无效");
		} catch (SignatureException e) {
			throw new IFSException(e,"SignUtil.veriSign.97","验签失败：signature执行验签失败");
		}catch (Exception e) {
			throw new IFSException(e, "SignUtil.veriSign.99", "验签失败");
		}
	}
	/**
	 * 验签(使用系统证书验签签名)
	 * @author liangcz
	 * @date   2017年12月1日 下午7:56:34
	 * @return boolean
	 */
	public boolean veriSign(String signCode, String signMsg) {
		try {
			return veriSign(signCode,signMsg,keyFactory.getCert());
		}  catch(IFSException e) {
			throw e;
		}catch (Exception e) {
			throw new IFSException(e, "SignUtil.veriSign.99", "验签(使用系统证书验签签名)失败");
		}
	}
}
